package mh;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Hashtable;

import mh.interfaces.Constants;

/**
 * Handles IO communication with files to read parameters.
 * 
 * @author Gianmarco Laggia
 * 
 */
public class Connectivity implements Constants {

	//	private static ClientTCP	clientTCP;
	//	private static Thread		TCPThread;
	//	private static ClientUDP	clientUDP;
	//	private static Thread		UDPThread;

	//	public Connectivity(MagicHogwarts g) {
	// clientTCP = new ClientTCP(g);
	// TCPThread = new Thread(clientTCP, "ClientTCP");
	// TCPThread.run();
	//
	// clientUDP = new ClientUDP(g);
	// UDPThread = new Thread(clientUDP, "ClientUDP");
	// UDPThread.run();
	//	}

	//	public static void sendMovement(String message) {
	//		if (Connectivity.TCPThread.isAlive()) {
	//			clientTCP.send(message);
	//		}
	//	}
	//
	//	public static void sendAction(String message) {
	//		if (Connectivity.TCPThread.isAlive()) {
	//			clientTCP.send(message);
	//		}
	//	}

	/**
	 * This is a static method that allows to read from files.<br>
	 * The return is an ArrayList of Strings, each record is a line of the file.<br>
	 * Coded in UTF-8.
	 * 
	 * @param filename
	 *            The name of the file you want to read.
	 * @return An arrayList of the lines.
	 * @throws FileNotFoundException
	 *             Thrown if the file is not found or is a directory.
	 * @throws IOException
	 *             Thrown if some error occurs in the buffer
	 */
	public static ArrayList<String> readLinesFromFile(String filename) throws FileNotFoundException, IOException {

		if ((filename == null) || "".equals(filename)) {
			throw new IllegalArgumentException();
		}
		ArrayList<String> lines = new ArrayList<String>();
		File file = new File(MAIN_FOLDER + filename);
		FileReader fileReader = new FileReader(file);
		BufferedReader buffer = new BufferedReader(fileReader);
		String s;
		while ((s = buffer.readLine()) != null) {
			String UTF8Str = new String(s.getBytes(), "UTF-8");
			lines.add(UTF8Str);
		}
		buffer.close();
		return lines;
	}

	/**
	 * This is a static method that allows to read from files.<br>
	 * The return is an ArrayList of Pair, each record contains the param and its value.<br>
	 * Coded in UTF-8. Uses ; as start of comment.
	 * 
	 * @param filename
	 *            The name of the file you want to read.
	 * @param splitter
	 *            The string used to split each param and value
	 * @return An arrayList of Pair of param+value.
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	public static Hashtable<String, String> readParamsFromFile(String filename, String splitter) throws FileNotFoundException, IOException {

		if ((filename == null) || (splitter == null) || "".equals(filename)) {
			throw new IllegalArgumentException();
		}
		Hashtable<String, String> lines = new Hashtable<String, String>();
		File file = new File(MAIN_FOLDER + filename);
		FileReader fileReader = new FileReader(file);
		BufferedReader buffer = new BufferedReader(fileReader);
		String s;
		while ((s = buffer.readLine()) != null) {
			if (!s.startsWith(COMMENT_STARTER)) {
				String UTF8Str = new String(s.getBytes(), "UTF-8");
				String[] arr = UTF8Str.split(splitter);
				if (arr.length > 2) {
					arr[1] = "ERR_NOT_VALID";
				}
				lines.put(arr[0].trim(), arr[1].trim());
			}
		}
		buffer.close();
		return lines;
	}

	/**
	 * Writes params to a file, one per line, divided by the <code>splitter</code> string.<br>
	 * If a param is already present in the file it will be updated with the new <code>value</code>. Any
	 * <code>comment</code> in this case is ignored.<br>
	 * If the param is new it will write first the comment line (at the moment in a single line), the it will add the
	 * combination of params, splitter and value<br>
	 * 
	 * @param filename
	 *            The name of the file you want to work with. Must exists
	 * @param splitter
	 *            The string used to split each param and value
	 * @param paramName
	 *            The name of the new param, or the param to edit
	 * @param value
	 *            The new value of the param
	 * @param comment
	 *            The comment for a new param
	 * @throws FileNotFoundException
	 *             If the file don't exists
	 * @throws IOException
	 *             Any other error in writing or reading.
	 */
	public static void writeParamsToFile(String filename, String splitter, String paramName, String value, String comment) throws FileNotFoundException, IOException {
		if ((filename == null) || (splitter == null) || "".equals(filename) || (paramName == null) || "".equals(paramName)) {
			throw new IllegalArgumentException();
		}
		ArrayList<String> lines = new ArrayList<String>();
		Hashtable<String, String> params = new Hashtable<String, String>();
		File file = new File(MAIN_FOLDER + filename);
		FileReader fileReader = new FileReader(file);
		BufferedReader bufferR = new BufferedReader(fileReader);
		String s;
		while ((s = bufferR.readLine()) != null) {
			if (!s.startsWith(COMMENT_STARTER)) {
				String UTF8Str = new String(s.getBytes(), "UTF-8");
				String[] arr = UTF8Str.split(splitter);
				if (arr.length > 2) {
					arr[1] = "ERR_NOT_VALID";
				}
				lines.add(arr[0].trim().toUpperCase());
				params.put(arr[0].trim().toUpperCase(), arr[1].trim());
			} else {
				lines.add(s);
			}
		}
		bufferR.close();
		FileWriter fileWriter = new FileWriter(file);
		BufferedWriter bufferW = new BufferedWriter(fileWriter);
		PrintWriter out = new PrintWriter(bufferW);
		boolean alreadyPresent = false;
		for (int i = 0; i < lines.size(); i++) {
			if (lines.get(i).startsWith(COMMENT_STARTER)) {
				out.println(lines.get(i));
			} else {
				if (!paramName.equalsIgnoreCase(lines.get(i))) {
					out.println(lines.get(i).toUpperCase() + splitter + params.get(lines.get(i).toUpperCase()));
				} else {
					alreadyPresent = true;
					out.println(lines.get(i).toUpperCase() + splitter + value);
				}
			}
		}
		if (!alreadyPresent) {
			if ((comment != null) && !"".equals(comment)) {
				out.println(COMMENT_STARTER + comment);
			}
			out.println(paramName.toUpperCase() + splitter + value);
		}
		out.close();
	}
}
